//! 资源层级结构
//!
//! 定义资源的层级关系，支持层级回退查询

use serde::{Deserialize, Serialize};

/// 层级级别
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u8)]
pub enum HierarchyLevel {
    /// 一级（如省级）
    Level1 = 1,
    /// 二级（如市级）
    Level2 = 2,
    /// 三级（如区级）
    Level3 = 3,
    /// 自定义级别
    Custom = 99,
}

/// 资源层级结构
///
/// 定义资源的层级关系，支持从低级到高级的回退查询
///
/// # 示例
///
/// ```ignore
/// // 三级层级：省 -> 市 -> 区
/// let hierarchy = ResourceHierarchy::three_level(
///     "610000", "陕西省",
///     "610100", "西安市",
///     "610102", "新城区"
/// );
///
/// // 回退顺序：区 -> 市 -> 省
/// let fallback = hierarchy.fallback_order();
/// assert_eq!(fallback, vec!["610102", "610100", "610000"]);
/// ```
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResourceHierarchy {
    /// 层级列表（从高到低：省 -> 市 -> 区）
    levels: Vec<HierarchyNode>,
}

/// 层级节点
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HierarchyNode {
    /// 节点代码
    pub code: String,
    /// 节点名称
    pub name: String,
    /// 层级级别
    pub level: HierarchyLevel,
}

impl ResourceHierarchy {
    /// 创建单级层级
    pub fn single_level(
        code: impl Into<String>,
        name: impl Into<String>,
    ) -> Self {
        Self { levels: vec![HierarchyNode { code: code.into(), name: name.into(), level: HierarchyLevel::Level1 }] }
    }

    /// 创建两级层级
    pub fn two_level(
        level1_code: impl Into<String>,
        level1_name: impl Into<String>,
        level2_code: impl Into<String>,
        level2_name: impl Into<String>,
    ) -> Self {
        Self {
            levels: vec![
                HierarchyNode { code: level1_code.into(), name: level1_name.into(), level: HierarchyLevel::Level1 },
                HierarchyNode { code: level2_code.into(), name: level2_name.into(), level: HierarchyLevel::Level2 },
            ],
        }
    }

    /// 创建三级层级
    pub fn three_level(
        level1_code: impl Into<String>,
        level1_name: impl Into<String>,
        level2_code: impl Into<String>,
        level2_name: impl Into<String>,
        level3_code: impl Into<String>,
        level3_name: impl Into<String>,
    ) -> Self {
        Self {
            levels: vec![
                HierarchyNode { code: level1_code.into(), name: level1_name.into(), level: HierarchyLevel::Level1 },
                HierarchyNode { code: level2_code.into(), name: level2_name.into(), level: HierarchyLevel::Level2 },
                HierarchyNode { code: level3_code.into(), name: level3_name.into(), level: HierarchyLevel::Level3 },
            ],
        }
    }

    /// 获取当前层级的代码
    pub fn current_code(&self) -> &str {
        self.levels.last().map(|n| n.code.as_str()).unwrap_or("")
    }

    /// 获取当前层级的名称
    pub fn current_name(&self) -> &str {
        self.levels.last().map(|n| n.name.as_str()).unwrap_or("")
    }

    /// 获取当前层级级别
    pub fn current_level(&self) -> HierarchyLevel {
        self.levels.last().map(|n| n.level).unwrap_or(HierarchyLevel::Custom)
    }

    /// 获取回退顺序（从当前层级到顶层）
    ///
    /// 返回代码列表，按优先级从高到低排序
    pub fn fallback_order(&self) -> Vec<String> {
        self.levels.iter().rev().map(|n| n.code.clone()).collect()
    }

    /// 获取所有层级节点
    pub fn all_levels(&self) -> &[HierarchyNode] {
        &self.levels
    }

    /// 获取指定级别的节点
    pub fn get_level(
        &self,
        level: HierarchyLevel,
    ) -> Option<&HierarchyNode> {
        self.levels.iter().find(|n| n.level == level)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_single_level() {
        let hierarchy = ResourceHierarchy::single_level("610000", "陕西省");
        assert_eq!(hierarchy.current_code(), "610000");
        assert_eq!(hierarchy.fallback_order(), vec!["610000"]);
    }

    #[test]
    fn test_three_level() {
        let hierarchy = ResourceHierarchy::three_level("610000", "陕西省", "610100", "西安市", "610102", "新城区");

        assert_eq!(hierarchy.current_code(), "610102");
        assert_eq!(hierarchy.fallback_order(), vec!["610102", "610100", "610000"]);
    }
}
